package cn.xuqiudong.console.module.system.service;

import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.common.base.service.BaseService;
import cn.xuqiudong.console.module.system.mapper.SysMenuMapper;
import cn.xuqiudong.console.module.system.model.SysMenu;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 菜单表 Service
 * @author Vic.xu
 */
@Service
public class SysMenuService extends BaseService<SysMenuMapper, SysMenu> {

    /**
     * 菜单code的起始值:从100开始每级别占三位,同级别递增
     */
    private static long START_MENU_CODE = 100L;


    /**
     * 全部的菜单列表
     * @return
     */
    public List<SysMenu> allMenus() {
        List<SysMenu> menus = mapper.list(new SysMenu());
        return menus;
    }

    /**
     * 查询出全部可用的菜单的树形结构
     * @return
     */
    public List<SysMenu> menuTree() {
        List<SysMenu> menus = allMenus();
        if (CollectionUtils.isEmpty(menus)) {
            return menus;
        }
        return buildMenuTree(menus);

    }

    /**
     * 新增菜单
     * @param entity
     * @return
     */
    @Override
    public int save(SysMenu entity) {
        if (entity.getId() == null) {
            // 新增需要生成code
            entity.setCode(getCodeByPid(entity.getPid()));
        }
        return super.save(entity);
    }

    /**
     *根据pid获得当前code
     *菜单code的起始值:从100开始每级别占三位,同级别递增
     * @param pid
     * @return
     */
    private long getCodeByPid(Integer pid) {
        // 1 -当前节点就是根节点 且找不同级别的code 则表示这个菜单是第一个菜单
        if (pid == null || pid == 0) {
            return START_MENU_CODE;
        }

        Long curMaxCode = mapper.getMaxCode(pid);
        if (curMaxCode != null) {
            return curMaxCode.longValue() + 1;
        }

        //2 当前节点不是根节点 但是找不到同节点的最大节点 则表示当前菜单是父节点下的第一个节点
        SysMenu parent = findById(pid);
        if (parent == null) {
            //TODO 异常统一处理
            throw new RuntimeException("不存在的父节点菜单");
        }
        return Long.parseLong(parent.getCode() + "001");
    }


    /**
     * 构建菜单树方法
     * @param list
     * @return
     */
    private List<SysMenu> buildMenuTree(List<SysMenu> list) {
        Map<Integer, SysMenu> menuMap = new LinkedHashMap<Integer, SysMenu>();
        List<SysMenu> menuTree = new ArrayList<SysMenu>();
        for (SysMenu m : list) {
            menuMap.put(m.getId(), m);
        }
        for (Map.Entry<Integer, SysMenu> entry : menuMap.entrySet()) {
            SysMenu menu = entry.getValue();
            //根节点
            if (menu.isRoot()) {
                menuTree.add(menu);
            } else {//子节点
                SysMenu parent = menuMap.get(menu.getPid());
                if (parent != null) {
                    parent.addChildren(menu);
                }
            }
        }
        return menuTree;

    }

    public static void main(String[] args) throws JsonProcessingException {
        SysMenu m1 = new SysMenu().setName("1111").setPid(0);
        m1.setId(1);
        SysMenu m2 = new SysMenu().setName("2222").setPid(1);
        m1.setId(2);
        SysMenu m3 = new SysMenu().setName("3333").setPid(1);
        m1.setId(3);
        List<SysMenu> list = new ArrayList<SysMenu>();
        list.add(m1);
        list.add(m2);
        list.add(m3);
        List<SysMenu> tree = new SysMenuService().buildMenuTree(list);
        BaseResponse<?> b = BaseResponse.success(tree);
        String json = new ObjectMapper().writeValueAsString(b);
        System.out.println(json);
    }

    /**
     * 用作选择当前菜单父级菜单
     */
    public List<SysMenu> chooseParent() {
        List<SysMenu> list = mapper.chooseParent();
        return list;
    }

    @Override
    protected boolean hasAttachment() {
        return false;
    }

}
